package com.tim.third.utils;

import org.apache.commons.lang3.*;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.commons.lang3.reflect.ConstructorUtils;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.apache.commons.lang3.reflect.InheritanceUtils;
import org.apache.commons.lang3.reflect.MethodUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.commons.lang3.time.DurationFormatUtils;

import java.lang.reflect.Constructor;
import java.time.DayOfWeek;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;


/**
 * http://commons.apache.org/index.html
 */
public class ApacheCommon {
	public static void main(String[] args) {
		
	}
	
	/**
	 * 
		<dependency>
		  <groupId>org.apache.commons</groupId>
		  <artifactId>commons-lang3</artifactId>
		  <version>3.12.0</version>
		</dependency>
	 */
    public static void lang3(){
    	
    	// 数组工具；增删改查，交换反转等
    	ArrayUtils.reverse(new int[]{1,2,4,3});
		// 布尔工具；
    	BooleanUtils.and(new boolean[]{true, false, true});
		// 字符集合工具。压缩、查找等
		CharSetUtils.squeeze("", "");
		// 字符工具。类型转换、ascii判断
		CharUtils.toChar("a");
		// 项目内路径处理
		ClassPathUtils.toFullyQualifiedName((Class)null, "");
		// 类工具
		ClassUtils.getCanonicalName(ApacheCommon.class);
		// 枚举工具；map、list；按名称获取
		EnumUtils.getEnumMap(DayOfWeek.class);
		// 对象工具；比较、判空、克隆
		ObjectUtils.allNotNull("", 1);
		// 随机数；
		RandomUtils.nextInt(1,1000);
		RandomStringUtils.random(123);
		// 字符串工具
        StringUtils.isNotBlank("");

    }

	public static void lang3Pkg() throws Exception {
    	// 数值工具；转换、比较
		NumberUtils.toInt("");
		// 构造器工具
		ConstructorUtils.invokeConstructor(ApacheCommon.class, ArrayUtils.EMPTY_CHARACTER_OBJECT_ARRAY);
		// 方法
		MethodUtils.invokeMethod(null, "");
		// 变量工具
		FieldUtils.getAllFields(String.class);
		// 继承判断
		InheritanceUtils.distance(String.class, CharSequence.class);
		// 格式化
		DateFormatUtils.format(new Date(), "yyyy");
		// 解析时间
		DateUtils.parseDate("2021", "yyyy");
		// 格式化duration
		DurationFormatUtils.formatDuration(1234, "s");
	}


	
	public static void arrayUtils() throws Exception {
		// 空数组
		int[] ints = ArrayUtils.EMPTY_INT_ARRAY;
		// 添加
		ints = ArrayUtils.add(ints, 3);
		ints = ArrayUtils.add(ints, 1);
		System.out.println(ArrayUtils.toString(ints));
		// 索引值
		ArrayUtils.indexOf(ints, 1);
		System.out.println(ArrayUtils.toString(ints));
		// 删除
		ints = ArrayUtils.remove(ints, 1);
		System.out.println(ArrayUtils.toString(ints));
		// 插入
		ints = ArrayUtils.insert(0,ints, 3,5,2,1);
		System.out.println(ArrayUtils.toString(ints));
		// 反转
		ArrayUtils.reverse(ints);
		System.out.println(ArrayUtils.toString(ints));
		// 交换
		ArrayUtils.swap(ints, 1, 3);
		System.out.println(ArrayUtils.toString(ints));
		// 克隆
		System.out.println(ArrayUtils.toString(ArrayUtils.clone(ints)));
		// 子串
		System.out.println(ArrayUtils.toString(ArrayUtils.subarray(ints,1,3)));

	}

	
	public static void booleanUtils() throws Exception {
		// 运算；与、或、异或
		System.out.println(BooleanUtils.and(new boolean[]{true, false, true}));
		System.out.println(BooleanUtils.or(new boolean[]{true, false, true}));
		System.out.println(BooleanUtils.xor(new Boolean[]{true, false, true}));
		// 转换
		System.out.println(BooleanUtils.toBoolean(1));
	}

	
	public static void charSetUtils() throws Exception {
		// 压缩；类正则[]。k-p，^k，^a-c。从左至右匹配，"a^"匹配a和^，^单字符、首范围取反。
		System.out.println(CharSetUtils.squeeze("hellloll hellol helo ", "k-p"));
		// 包含
		System.out.println(CharSetUtils.containsAny("hellloll", "x-y", "^a-d"));
		// 计数
		System.out.println(CharSetUtils.count("helllollxa", "x-y", "^a-d"));
		System.out.println(CharSetUtils.count("helllollxb", "^a-dx-y"));// 对a-d取反
		System.out.println(CharSetUtils.count("helllollxb", "^a-d^x-y"));// 对a-d取反
		// 保留
		System.out.println(CharSetUtils.keep("helllollxa", "x-y", "^a-d"));
		// 删除
		System.out.println(CharSetUtils.delete("helllollxa", "x-y", "^a-d"));

	}

	
	public static void charUtils() throws Exception {
		// 首字符转char
		System.out.println(CharUtils.toChar("str"));
		// 字符转数值。1--1，非数值报错
		System.out.println(CharUtils.toIntValue('1'));

	}

	
	public static void classPathUtils() throws Exception {
		//不带项目路径
		// 同包下资源全名
		System.out.println(ClassPathUtils.toFullyQualifiedName(ApacheCommon.class, "hello"));
		// 同包下资源全名
		System.out.println(ClassPathUtils.toFullyQualifiedName(ApacheCommon.class.getPackage(), "hello"));
		// 同包下资源路径
		System.out.println(ClassPathUtils.toFullyQualifiedPath(ApacheCommon.class.getPackage(), "hello"));
		// 同包下资源路径
		System.out.println(ClassPathUtils.toFullyQualifiedPath(ApacheCommon.class.getPackage(), "hello"));

	}

	
	public static void classUtils() throws Exception {
		// 类名、类全名
		System.out.println(ClassUtils.getSimpleName(ApacheCommon.class));
		System.out.println(ClassUtils.getName(ApacheCommon.class));
		// 类层级。子-父。
		ClassUtils.hierarchy(ArrayList.class, ClassUtils.Interfaces.INCLUDE).forEach(System.out::println);
		// 接口
		ClassUtils.getAllInterfaces(ArrayList.class).forEach(System.out::println);
		// 父类
		ClassUtils.getAllSuperclasses(ArrayList.class).forEach(System.out::println);
		// 转Class[]
		System.out.println(ArrayUtils.toString(ClassUtils.toClass(1, 1.1, false, 'c', "")));
		// 获取方法
		System.out.println(ClassUtils.getPublicMethod(ArrayList.class, "get", ClassUtils.toClass(1)));

	}

	
	public static void enumUtils(){
		// map、list；按名称获取
		System.out.println(EnumUtils.getEnumMap(DayOfWeek.class));
		System.out.println(EnumUtils.getEnumList(DayOfWeek.class));
		System.out.println(EnumUtils.getEnumIgnoreCase(DayOfWeek.class, "Tuesday"));
	}

	
	public static void objectUtils(){
		// 判空
		System.out.println(ObjectUtils.allNotNull(1, null));
		// 比较
		System.out.println(ObjectUtils.compare(1, 2));
		System.out.println(ObjectUtils.min(1, 2));
		System.out.println(ObjectUtils.max(1, 2));
		System.out.println(ObjectUtils.median(1, 2, 6, 9 , -1, 5));
		System.out.println(ObjectUtils.median(Comparator.<Integer>naturalOrder().reversed(), 1, 2, 6, 9 , -1, 5));
		// 克隆
		System.out.println(ObjectUtils.clone(1));
	}

	
	public static void randomUtils(){
		// 随机数
		System.out.println(RandomUtils.nextBoolean());
		System.out.println(RandomUtils.nextBytes(12).length);
		System.out.println(RandomUtils.nextInt());
		System.out.println(RandomUtils.nextLong());
		System.out.println(RandomUtils.nextDouble());
		System.out.println(RandomUtils.nextFloat());
	}

	
	public static void randomStringUtils(){
		// 长度为123的随机字符串，字符将从所有字符集中选择
		System.out.println(RandomStringUtils.random(12));
		// ascii为32-126的字符
		System.out.println(RandomStringUtils.randomAscii(12));
		// 长度10~12
		System.out.println(RandomStringUtils.randomAscii(10,12));
		// 字符为a-zA-Z
		System.out.println(RandomStringUtils.randomAlphabetic(12));
		System.out.println(RandomStringUtils.randomAlphabetic(10,12));
		// 字符为0-9
		System.out.println(RandomStringUtils.randomNumeric(12));
		System.out.println(RandomStringUtils.randomNumeric(10,12));
		// 指定字符
		System.out.println(RandomStringUtils.random(12, "1234"));
		System.out.println(RandomStringUtils.random(10, 'a', 'b'));
		// 字符为a-zA-Z0-9
		System.out.println(RandomStringUtils.randomAlphanumeric(12));
		System.out.println(RandomStringUtils.randomAlphanumeric(10,12));
		// 包含所有可见的 ASCII 字符（除空格和控制字符以外的任何字符）
		System.out.println(RandomStringUtils.randomGraph(12));
		System.out.println(RandomStringUtils.randomGraph(10,12));
		// 包含所有可见的 ASCII 字符（除控制字符以外的任何字符）
		System.out.println(RandomStringUtils.randomPrint(12));
		System.out.println(RandomStringUtils.randomPrint(10,12));

	}

	
	public static void stringUtils(){
		// 判空串
		System.out.println("StringUtils.isEmpty");
		System.out.println(StringUtils.isEmpty(""));
		System.out.println(StringUtils.isAllEmpty("", "1"));
		System.out.println(StringUtils.isAnyEmpty("", "1"));
		System.out.println(StringUtils.isNoneEmpty("", "1"));
		// 判空串、空白
		System.out.println("StringUtils.isBlank");
		System.out.println(StringUtils.isBlank(" "));
		System.out.println(StringUtils.isAllBlank(" ", "1"));
		System.out.println(StringUtils.isAnyBlank(" ", "1"));
		System.out.println(StringUtils.isNoneBlank(" ", "1"));
		// 替换空白
		StringUtils.stripAll(new String[]{"1"}, "");
		System.out.println(StringUtils.equalsIgnoreCase("a", "A"));
		System.out.println(StringUtils.equalsAnyIgnoreCase("a", "A", "c"));
		// 位置
		System.out.println(StringUtils.indexOfIgnoreCase("aasldFads", "f"));
		System.out.println(StringUtils.indexOfAny("aasldFads", "f", "sl"));
		System.out.println(StringUtils.indexOfAnyBut("aasldFads", 'f', 'a', 's'));
		// 包含
		System.out.println(StringUtils.containsIgnoreCase("aasldFads", "f"));
		System.out.println(StringUtils.containsOnly("aasldFads", "f"));
		System.out.println(StringUtils.containsAny("aasldFads", "f"));
		System.out.println(StringUtils.containsNone("aasldFads", "f"));
		// 子串
		System.out.println(StringUtils.substringBetween("tagabctag", "tag"));
		System.out.println(Arrays.toString(StringUtils.substringsBetween("tagabcatbag", "a", "b")));
		System.out.println(StringUtils.substringAfter("tagabctag", "tag"));
		System.out.println(StringUtils.substringBeforeLast("tagabctag", "bct"));
		// 集合转字符串
		System.out.println(StringUtils.join(new Object[]{null, "", "a"}, ',', 0, 3));
		// 移除
		System.out.println(StringUtils.removeStartIgnoreCase("www.domain.com", "WWW."));
		System.out.println(StringUtils.removeEndIgnoreCase("www.domain.com", ".COM"));
		// 替换
		System.out.println(StringUtils.replaceOnceIgnoreCase("FoOFoofoo", "foo", ""));
		System.out.println(StringUtils.replaceIgnoreCase("aba", "A", "z"));
		// 重复
		System.out.println(StringUtils.repeat("?, ", 3));
		// 补齐
		System.out.println(StringUtils.leftPad("bat", 5));
		System.out.println(StringUtils.leftPad("bat", 5, "??"));
		// 追加
		System.out.println(StringUtils.prependIfMissing("MNOabc", "xyz", "mno"));
		System.out.println(StringUtils.appendIfMissingIgnoreCase("abcMNO", "xyz", "mno"));

		// 包装、解包
		System.out.println(StringUtils.wrap("a", "'"));
		System.out.println(StringUtils.unwrap("'a'", "'"));
	}

	
	public static void numberUtils(){
		// 判断
		System.out.println(NumberUtils.isParsable("123L"));
		System.out.println(NumberUtils.isParsable("123.12"));
		// 转换
		System.out.println(NumberUtils.toInt("abc", 1));
		System.out.println(NumberUtils.toLong("123L", 1));
		System.out.println(NumberUtils.toLong("123", 1));
		// 比较
		System.out.println(NumberUtils.max(1,3,2,34,123423,546,123,4567,1234));

	}

	
	public static void constructorUtils() throws Exception {
		// 获取构造器
		Constructor<ApacheCommon> constructor = ConstructorUtils.getAccessibleConstructor(ApacheCommon.class, new Class[0]);
		System.out.println(constructor);
		// 判断访问权限，非public返回null
		System.out.println(ConstructorUtils.getAccessibleConstructor(constructor));
		// 执行；匹配，严格匹配
		System.out.println(ConstructorUtils.invokeConstructor(ApacheCommon.class, new Object[0]));
		System.out.println(ConstructorUtils.invokeExactConstructor(ApacheCommon.class, new Object[0]));


	}

	
	public static void methodUtils() throws Exception {
		// 执行
		System.out.println(MethodUtils.invokeMethod("aakljdfh", true, "length"));
		// 获取方法
		System.out.println(MethodUtils.getAccessibleMethod(String.class, "length"));
		// 获取注解
		MethodUtils.getAnnotation(null, null, true, true);
	}

	
	public static void fieldUtils() throws Exception {
		// 获取
		System.out.println(Arrays.toString(FieldUtils.getAllFields(String.class)));
		// 读
		String str = "lalala";
		FieldUtils.readField(str, "value", true);
		System.out.println(str);
		// 写
		FieldUtils.writeField(str, "value", new char[]{}, true);
		System.out.println(str);
		System.out.println("end");
	}

	
	public static void inheritanceUtils() throws Exception {
		// 继承代数
		System.out.println(InheritanceUtils.distance(String.class, CharSequence.class));
	}

	
	public static void timeUtils() throws Exception {
		// 格式化？yMd，HmsS
		System.out.println(DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss.SSS"));
		// 解析时间
		System.out.println(DateUtils.parseDate("2021", "yyyy"));
		// 解析时间段；
		System.out.println(DurationFormatUtils.formatDuration(1234, "s"));
	}


}
